package manager
{
	
	import flash.display.*;
	import flash.events.*;
	
	import model.UserPx;
	import view.*;
	import log.Logger;
	import event.*;
	
	/**
	 * -- ViewMgr --
	 * @desc	view manager, in charge of displaying UI
	 * @author	Aqua (built on 2011-11-09)
	 */
	public class ViewMgr
	{
		//---------------------//
		//      Singleton      //
		//---------------------//
		
		/**************************************************************************
		 * -- (getter) instance --
		 * @desc		get singleton of this class
		 * @return		singleton of this class
		 *************************************************************************/
		public static function get instance():ViewMgr
		{
			if (null == _instance)
			{
				_instance = new ViewMgr(singleton);
			}
		
			return _instance;
		}
		
		/**************************************************************************
		 * -- singleton --
		 * @desc		a private function used to enforce singlton
		 *************************************************************************/
		private static function singleton():void
		{
			
		}
		
		
		//---------------------//
		//     Constructor     //
		//---------------------//
		
		/**************************************************************************
		 * -- ViewMgr --
		 * @desc		constructor
		 * @param		(s) a private function used to enforce singlton
		 *************************************************************************/
		public function ViewMgr(s:Function = null):void
		{
			if (singleton != s)
			{
				throw new Error("This is a singleton class!");
			}
		}
		
		
		//-----------------//
		//     Publics     //
		//-----------------//
		
		/**************************************************************************
		 * -- init --
		 * @desc		initialize layers, and views
		 * @param		(main) parent of all objects on stage
		 *************************************************************************/
		public function init(main:DisplayObjectContainer):void
		{
			var i:int;
			var layer:Sprite;
			
			_evt = EvtDispatcher.instance;
			_main = main;
			_layerList = [];
			_menuIndex = -1;
			i = 0;
			
			while (i < NUM_LAYERS)
			{
				layer = new Sprite();
				_main.addChild(layer);
				_layerList[i] = layer;
				i ++;
			}
						
			_viewList = { };
			_viewList[ChooseCampView.VIEW_NAME]		= new ChooseCampView(new choose_camp());
			_viewList[UserInfoBoardView.VIEW_NAME]	= new UserInfoBoardView(new user_info_board());
			_viewList[MainMenuView.VIEW_NAME]		= new MainMenuView(new main_menu());
			_viewList[GameInfoBarView.VIEW_NAME]	= new GameInfoBarView(new game_info_bar());
			_viewList[StageListView.VIEW_NAME]		= new StageListView(new stage_list());
			_viewList[StageDetailView.VIEW_NAME]	= new StageDetailView(new stage_detail());
			_viewList[TeamView.VIEW_NAME]			= new TeamView(new team());
			_viewList[BattleView.VIEW_NAME]			= new BattleView(new battle());
			
			_userPx	= ProxyMgr.instance.getProxy(UserPx.NAME) as UserPx;
			
			addListeners();
		}
		
		/**************************************************************************
		 * -- startUp --
		 * @desc		start to show UI
		 *************************************************************************/
		public function startUp():void
		{
			if (_userPx.isNewComer)
			{
				addView(ChooseCampView.VIEW_NAME, ChooseCampView.LAYER_INDEX);
			}
			
			addView(MainMenuView.VIEW_NAME, MainMenuView.LAYER_INDEX);
			addView(UserInfoBoardView.VIEW_NAME, UserInfoBoardView.LAYER_INDEX);
			addView(GameInfoBarView.VIEW_NAME, GameInfoBarView.LAYER_INDEX);
			
			setMenu(TEAM);
		}
		
		/**************************************************************************
		 * -- (getter) menuIndex --
		 * @desc		get chosen menu's index
		 * @return		index of menu
		 *************************************************************************/
		public function get menuIndex():int
		{
			return _menuIndex;
		}
		
		/**************************************************************************
		 * -- setMenu --
		 * @desc		set a menu page
		 * @param		(index) index of page
		 *************************************************************************/
		public function setMenu(index:int):void
		{
			if (index == _menuIndex)
			{
				return;
			}
			
			switch(_menuIndex)
			{
				case TEAM:		// 编成
					removeView(TeamView.VIEW_NAME, TeamView.LAYER_INDEX);
					break;
				case EXPLORE:	// 探险
					removeView(StageListView.VIEW_NAME, StageListView.LAYER_INDEX);
					removeView(StageDetailView.VIEW_NAME, StageDetailView.LAYER_INDEX);
					break;
				case DUEL:		// 决斗
					// for test
					removeView(BattleView.VIEW_NAME, BattleView.LAYER_INDEX);
				default:
					break;
			}
			
			_menuIndex = index;
			BaseView(_viewList[MainMenuView.VIEW_NAME]).onRefresh();
			
			switch(_menuIndex)
			{
				case TEAM:		// 编成
					addView(TeamView.VIEW_NAME, TeamView.LAYER_INDEX);
					break;
				case EXPLORE:	// 探险
					addView(StageListView.VIEW_NAME, StageListView.LAYER_INDEX);
					break;
				case DUEL:		// 决斗
					// for test
					addView(BattleView.VIEW_NAME, BattleView.LAYER_INDEX);
				default:
					break;
			}
		}
		
		
		//------------------//
		//     Privates     //
		//------------------//
		
		/**************************************************************************
		 * -- addView --
		 * @desc		add a view to stage
		 * @param		(viewName) name of this view
		 *************************************************************************/
		private function addView(viewName:String, layerIndex:int):void
		{
			var bv:BaseView;
			var layer:Sprite;
			
			bv = _viewList[viewName];
			layer = _layerList[layerIndex];
			
			if (null == layer.getChildByName(viewName))
			{
				Logger.log("add view: " + viewName);
				bv.onAdd();
				layer.addChild(bv.viewComponent);
			}
		}
		
		/**************************************************************************
		 * -- removeView --
		 * @desc		remove a view from stage
		 * @param		(viewName) name of this view
		 *************************************************************************/
		private function removeView(viewName:String, layerIndex:int):void
		{
			var bv:BaseView;
			var layer:Sprite;
			
			bv = _viewList[viewName];
			layer = _layerList[layerIndex];
			
			if (null != layer.getChildByName(viewName))
			{
				Logger.log("remove view: " + viewName);
				layer.removeChild(bv.viewComponent);
				bv.onRemove();
			}
		}
		
		/**************************************************************************
		 * -- addListeners --
		 * @desc		add all event listeners
		 *************************************************************************/
		private function addListeners():void
		{
			_evt.addEventListener(Evt.CHOOSE_CAMP, onEvt);
			_evt.addEventListener(Evt.CHOOSE_STAGE, onEvt);
			_evt.addEventListener(Evt.RETURN_TO_LIST, onEvt);
			_evt.addEventListener(Evt.ENTER_STAGE, onEvt);
		}
		
		/**************************************************************************
		 * -- onEvt --
		 * @desc		event handler
		 * @param		(e) event information
		 *************************************************************************/
		private function onEvt(e:Event):void
		{
			switch(e.type)
			{
				case Evt.CHOOSE_CAMP:
					removeView(ChooseCampView.VIEW_NAME, ChooseCampView.LAYER_INDEX);
					break;
				case Evt.CHOOSE_STAGE:
					addView(StageDetailView.VIEW_NAME, StageDetailView.LAYER_INDEX);
					break;
				case Evt.RETURN_TO_LIST:
					removeView(StageDetailView.VIEW_NAME, StageDetailView.LAYER_INDEX);
					break;
				case Evt.ENTER_STAGE:
					removeView(StageDetailView.VIEW_NAME, StageDetailView.LAYER_INDEX);
					addView(BattleView.VIEW_NAME, BattleView.LAYER_INDEX);
					break;
				default:
					break;
			}
		}
		
		
		private static var _instance:ViewMgr;
		
		private const NUM_LAYERS:int = 8;
		
		private const TEAM		:int = 0;
		private const EXPLORE	:int = 1;
		private const DUEL		:int = 2;
		
		private var _evt		:EvtDispatcher;
		private var _main		:DisplayObjectContainer;
		private var _viewList	:Object;
		private var _layerList	:Array;
		private var _menuIndex	:int;
		
		private var _userPx		:UserPx;
	}
	
}